﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.IO;
using System.Windows.Markup;
using System.Windows.Controls;
using System.IO.Packaging;
using System.Windows.Xps.Packaging;
using System.Windows.Xps.Serialization;
using InHD.viewmodels;
using System.Windows;
using System.Collections.ObjectModel;
using System.Data;
using System.Windows.Media;
using InHD.dataaccess;
using System.Data.SqlClient;
using InHD.Properties;

namespace InHD.utilities
{
    class InvoicePrinter:WorkspaceViewModel
    {
        private FixedDocumentSequence _myDocument;
        public FixedDocumentSequence MyDocument {
            get 
            {
                return _myDocument;
            }
            set
            {
                _myDocument = value;
            }
        }

        private InvoiceTemplateRepository invoiceTemplateRepo = new InvoiceTemplateRepository();
        private FlowDocument MyFlowDocument;
        private string InvoiceTemplateUNK;
        private byte[] InvoiceTemplateContent;
        private bool isTemplateError = false;


        #region Constructor

        /// <summary>
        /// Constructor with Invoice Template ID
        /// </summary>
        /// <param name="invoiceTemplateUNK"></param>
        public InvoicePrinter(string invoiceTemplateUNK)
        {
            this.InvoiceTemplateUNK = invoiceTemplateUNK;
            this.LoadTemplate(this.InvoiceTemplateUNK);
        }

        public InvoicePrinter(byte[] invoiceTemplateContent)
        {
            this.InvoiceTemplateContent = invoiceTemplateContent;
            this.LoadTemplate(this.InvoiceTemplateContent);
        }

        #endregion

        #region Method 

        private bool LoadTemplate(string templateUNK)
        {
            byte[] invoiceTemplateContent = invoiceTemplateRepo.GetInvoiceContent(templateUNK);
            try
            {
                MemoryStream stream = new MemoryStream(invoiceTemplateContent);
                MyFlowDocument = XamlReader.Load(stream) as FlowDocument;
                MyFlowDocument.ColumnWidth = new PrintDialog().PrintableAreaWidth;
                stream.Close();
                return true;
            }
            catch (Exception ex)
            {
                this.isTemplateError = true;
                MessageBox.Show("Failed to load Template with id = " + this.InvoiceTemplateUNK, Resources.App_Title, MessageBoxButton.OK, MessageBoxImage.Error );
                return false;
            }
        }

        private bool LoadTemplate(byte[] invoiceTemplateContent)
        {
             ///hard code
            try
            {
                MemoryStream stream = new MemoryStream(invoiceTemplateContent);
                MyFlowDocument = XamlReader.Load(stream) as FlowDocument;
                MyFlowDocument.ColumnWidth = new PrintDialog().PrintableAreaWidth;
                stream.Close();
                return true;
            }
            catch
            {
                this.isTemplateError = true;
                MessageBox.Show("Failed to load Template", Resources.App_Title, MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
        }

        public void PutSpan(string spanControlName, string value)
        {
            Span spanControl = System.Windows.LogicalTreeHelper.FindLogicalNode(MyFlowDocument as System.Windows.DependencyObject, spanControlName) as Span;
            if (spanControl == null) return;
            if (spanControl.Inlines.FirstInline != null)
            {
                ((Run)spanControl.Inlines.FirstInline).Text = value;
            }
            else
            {
                spanControl.Inlines.Add(value);
            }
        }

        public void PutDataTable(string tableName, DataTable content)
        {
            Table tableContent = System.Windows.LogicalTreeHelper.FindLogicalNode(MyFlowDocument as System.Windows.DependencyObject, tableName) as Table;
            if (tableContent == null)
            {
                MessageBox.Show("Load Template Failed!", Resources.App_Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }

            int numberColumn = content.Columns.Count;
            for (int i = 0; i < content.Rows.Count; i++)
            {
                TableRow row = new TableRow();
                for (int j = 0; j < numberColumn; j++)
                {
                    TableCell cell = new TableCell();
                    cell.TextAlignment = TextAlignment.Center;
                    if (j != numberColumn-1) cell.BorderThickness = new System.Windows.Thickness(0, 0, 1, 1);
                    else cell.BorderThickness = new System.Windows.Thickness(0, 0, 0, 1);
                    cell.BorderBrush = Brushes.Black;
                    Paragraph paragraph = new Paragraph();
                    paragraph.Inlines.Add(Convert.ToString(content.Rows[i][j]));
                    cell.Blocks.Add(paragraph);
                    row.Cells.Add(cell);
                }
                tableContent.RowGroups[0].Rows.Add(row);
            }
        }

        /// <summary>
        /// Show Print Preview
        /// </summary>
        public void ShowPrintPreview()
        {
            if (!isTemplateError)
            {
                MemoryStream ms = new MemoryStream();
                System.IO.Packaging.Package pkg = System.IO.Packaging.Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
                string pack = "pack://temp.xps";
                Uri tempPack = new Uri(pack);
                if (PackageStore.GetPackage(tempPack) == null)
                    PackageStore.AddPackage(tempPack, pkg);
                else
                {
                    PackageStore.RemovePackage(tempPack);
                    PackageStore.AddPackage(tempPack, pkg);
                }

                XpsDocument doc = new XpsDocument(pkg, CompressionOption.SuperFast, pack);
                XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(doc), false);
                DocumentPaginator pgn = ((IDocumentPaginatorSource)MyFlowDocument).DocumentPaginator;
                rsm.SaveAsXaml(pgn);
                MyDocument = doc.GetFixedDocumentSequence();
                InHD.views.usercontrols.PrintPreview previewDlg = new InHD.views.usercontrols.PrintPreview();
                previewDlg.DataContext = this;
                previewDlg.ShowDialog();
                PackageStore.RemovePackage(tempPack);
            }
        }

        public void Print(bool isUpdateInvoiceNumber)
        {
            if (isUpdateInvoiceNumber && !UpdateInvoiceNumber()) return;
            MemoryStream ms = new MemoryStream();
            System.IO.Packaging.Package pkg = System.IO.Packaging.Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
            string pack = "pack://temp.xps";
            Uri tempPack = new Uri(pack);
            if (PackageStore.GetPackage(tempPack) == null)
                PackageStore.AddPackage(tempPack, pkg);
            else
            {
                PackageStore.RemovePackage(tempPack);
                PackageStore.AddPackage(tempPack, pkg);
            }

            XpsDocument doc = new XpsDocument(pkg, CompressionOption.SuperFast, pack);
            XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(doc), false);
            DocumentPaginator pgn = ((IDocumentPaginatorSource)MyFlowDocument).DocumentPaginator;
            rsm.SaveAsXaml(pgn);
            MyDocument = doc.GetFixedDocumentSequence();
            PrintDialog dlg = new PrintDialog();
            if (dlg.ShowDialog() == true)
            {
                dlg.PrintDocument(MyDocument.DocumentPaginator, "");
            }
        }


        public bool UpdateInvoiceNumber()
        {
            bool result = true;
            String strConnect = "Data Source=" + Constants.Security.DefaultServer + "; Network Library=DBMSSOCN; Initial Catalog=inhd;User ID=" + Constants.Security.DefaultDBUser + ";Password=" + Constants.Security.DefaultDBPassword + ";";
            SqlConnection myConnection = new SqlConnection(strConnect);
            SqlTransaction myTransaction = null;
            string[] myParamName, myParamValue;
            try
            {
                myConnection.Open();
                myTransaction = myConnection.BeginTransaction();
                myParamName = new string[] {"@invoiceUNK"};
                myParamValue = new string[] { InvoiceTemplateUNK };
                DBUltils.RunStoreProcedure("UpdateInvoiceRegNumber", myParamName, myParamValue, myConnection, myTransaction);
                myTransaction.Commit();
                System.Windows.MessageBox.Show(Resources.InHD_TransactionCommited);
            }
            catch (SqlException ex)
            {
                myTransaction.Rollback();
                result = false;
                System.Windows.MessageBox.Show(Resources.InHD_DB_Error);
            }
            finally
            {
                myConnection.Close();
            }

            return result;
        }
        #endregion
    }
}
